/* This entire program is taken from Jason Mildrum, NT7S and Przemek Sadowski, SQ9NJE. There is not enough original code written by me to make it worth mentioning. http://nt7s.com/ http://sq9nje.pl/ http://ak2b.blogspot.com/ */ #include #include #include #include #define F_MIN 6900000L // Lower frequency limit #define F_MAX 7400000L #define ENCODER_A 3 // Encoder pin A #define ENCODER_B 2 // Encoder pin B #define ENCODER_BTN 11 #define LCD_RS 5 #define LCD_E 6 #define LCD_D4 7 #define LCD_D5 8 #define LCD_D6 9 #define LCD_D7 10 LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7); // LCD - pin assignement in Si5351 si5351; Rotary r = Rotary(ENCODER_A, ENCODER_B); volatile uint32_t vfo = 4000000L; //start freq - change to suit volatile uint32_t LSB = 4970000L; //change these to suit your needs volatile uint32_t USB = 5000500L; volatile uint32_t bfo = 11970000L; //start bfo freq volatile uint32_t radix = 1000; //start step size boolean changed_f = 0; String tbfo = "LSB"; /***/ /* Interrupt service routine for */ /* encoder frequency change */ /***/ ISR(PCINT2_vect) { unsigned char result = r.process(); if (result == DIR_CW) set_frequency(1); else if (result == DIR_CCW) set_frequency(-1); //display_frequency(); } /***/ /* Change the frequency */ /* dir = 1 Increment */ /* dir = -1 Decrement */ /***/ void set_frequency(short dir) { if(dir == 1) vfo += radix; if(dir == -1) vfo -= radix; display_frequency(); if(vfo > F_MAX) vfo = F_MAX; if(vfo < F_MIN) vfo = F_MIN; //display_frequency(); changed_f = 1; } /***/ /* Read the button with debouncing */ /***/ boolean get_button() { if(!digitalRead(ENCODER_BTN)) { delay(20); if(!digitalRead(ENCODER_BTN)) { while(!digitalRead(ENCODER_BTN)); return 1; } } return 0; } /***/ /* Displays the frequency */ /***/ void display_frequency() { uint16_t f, g; lcd.setCursor(4, 0); f = vfo / 1000000; //variable is now vfo instead of 'frequency' if(f<10) lcd.print(' '); lcd.print(f); lcd.print('.'); f = (vfo % 1000000)/1000; if(f<100) lcd.print('0'); if(f<10) lcd.print('0'); lcd.print(f); lcd.print('.'); f = vfo % 1000; if(f<100) lcd.print('0'); if(f<10) lcd.print('0'); lcd.print(f); lcd.print("Hz"); lcd.setCursor(0, 1); lcd.print(tbfo); //Serial.println(vfo + bfo); //Serial.println(tbfo); } /***/ /* Displays the frequency change step */ /***/ void display_radix() { lcd.setCursor(10, 1); switch(radix) { case 10: lcd.print(" 10"); break; case 100: lcd.print(" 100"); break; case 1000: lcd.print(" 1k"); break; case 10000: lcd.print(" 10k"); break; case 100000: lcd.print("100k"); break; } lcd.print("Hz"); } void setup() { Serial.begin(19200); lcd.begin(16, 2); // Initialize and clear the LCD lcd.clear(); Wire.begin(); // Start serial and initialize the Si5351 si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); // Set CLK0 to output 14 MHz with a fixed PLL frequency si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); si5351.set_freq(vfo, SI5351_CLK0); // Set CLK1 to output 20 MHz //si5351.set_freq(frequency1, 0, SI5351_CLK1); // Set CLK2 to output 15 MHz si5351.set_freq( bfo, SI5351_CLK2); si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_8MA); //si5351.drive_strength(SI5351_CLK1,SI5351_DRIVE_2MA); //si5351.drive_strength(SI5351_CLK2,SI5351_DRIVE_6MA); pinMode(ENCODER_BTN, INPUT_PULLUP); PCICR |= (1 << PCIE2); // Enable pin change interrupt for the encoder PCMSK2 |= (1 << PCINT18) | (1 << PCINT19); sei(); display_frequency(); // Update the display display_radix(); } void loop() { // Update the display if the frequency has been changed if(changed_f) { display_frequency(); si5351.set_freq(vfo + bfo, SI5351_CLK0); if(vfo >= 10000000L & tbfo != "USB") { bfo = USB; tbfo = "USB"; // si5351.set_freq( bfo, SI5351_CLK2); Serial.println("We've switched from LSB to USB"); } else if(vfo < 10000000L & tbfo != "LSB") { bfo = LSB; tbfo = "LSB"; // si5351.set_freq( bfo, SI5351_CLK2); Serial.println("We've switched from USB to LSB"); } changed_f = 0; } // Button press changes the frequency change step if(get_button()) { switch(radix) { case 10: radix = 100; break; case 100: radix = 1000; break; case 1000: radix = 10000; break; case 10000: radix = 100000; break; case 100000: radix = 10; break; } display_radix(); } }